#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_FUNCS_NUM 64
#define MAX_NAME_LENGTH 20
#define MIN_NAME_LENGTH 4
#define MAX_BUF_SIZE 64

// 恶意的函数集合
int SEN_FUNCS_NUM = 34;
char sensitive_func[MAX_FUNCS_NUM][MAX_NAME_LENGTH] = {
    "dlsym",
    "execve",
    "access", "open", "readdir", "fopen", "opendir", "fdopendir", "readdir64", "open64", "fopen64",
    "unlinkat", "unlink", "link", "symlink", "rmdir", "write", "kill", "rename",
    "stat", "lstat", "lxstat", "xstat", "__xstat", "__fxstat",
    "chmod", "chdir", "lchmod", "fchmod", "chown", "lchown",
    "ptrace", "getgid", "getregid"};

// 文件中的恶意函数集合
int FILE_SEN_FUNCS_NUM = 0;
// 文件的恶意函数的集合
char file_sensitive_func[MAX_NAME_LENGTH][MAX_FUNCS_NUM];

// 一个函数是恶意函数
int is_sensitive_func(const char *func)
{
    int result = 0;
    for (int i = 0; i < SEN_FUNCS_NUM; i++)
    {
        if (!strcmp(func, (const char *)&sensitive_func[i]))
            result = 1;
    }
    return result;
}

// 检测文件中的恶意函数串
void strings(FILE *fp)
{

    int c;
    char buf[MAX_BUF_SIZE];
    int index = 0;
    while (1)
    {
        c = getc(fp);
        if ((isprint(c) || c == '\t') && index < MAX_BUF_SIZE - 1)
            buf[index++] = c;
        else
        {
            if (index >= MIN_NAME_LENGTH)
            {
                buf[index] = '\0';
                if (is_sensitive_func((const char *)buf))
                {
                    FILE_SEN_FUNCS_NUM++;
                    strcpy((char *)&file_sensitive_func[FILE_SEN_FUNCS_NUM - 1], (const char *)buf);
                }
            }
            index = 0;
        }
        if (c == EOF)
            break;
    }
}

void info(char *filename)
{
    printf("evil func: ");
    for (int i = 0; i < FILE_SEN_FUNCS_NUM; i++)
    {
        printf("%s ", (char *)&file_sensitive_func[i]);
    }
    printf("\n");
}

int main(int argc, char *argv[])
{
    char buf[MAX_BUF_SIZE];
    FILE *fp;
    FILE *fp2;
    if ((fp = fopen("/etc/ld.so.preload", "r")) == NULL)
    {
        fprintf(stderr,"open /etc/ld.so.preload error.\n");
        exit(1);
    }
    else
    {
        while (fscanf(fp, "%[^\n]", buf) > 0)
        {
            printf("%s", buf);
            if ((fp2 = fopen(buf, "r")) == NULL)
            {
                fprintf(stderr,"open %s error.\n",buf);
                exit(1);
            }
            strings(fp2);
            // 恶意文件
            if (FILE_SEN_FUNCS_NUM > 5)
            {
                info((char *)buf);
                FILE_SEN_FUNCS_NUM = 0;
            }
        }
        close(fp);
    }
    return 0;
}